const mongoHelper = require('../lib/MongoHelper.js');
const settings = require('../settings-' + (process.env.profile || 'dev') + '.json');
const dfilecol = new mongoHelper.MongoCollection(settings['mongo_connect_url'], 'dfile', 10);

let instance_dict = {};

const isEmpty = function (obj) {
	for (var prop in obj) {
		if (obj.hasOwnProperty(prop)) return false;
	}
	return true;
}
/**
 * usage:
 * let dj = new dynamic_json.DynamicJSON('channel_list.json', 9,_=>{
 * 	console.log('dj ',dj.getSync());
 * });
 * 
 * let dj2 = new dynamic_json.DynamicJSON('channel_list.json', 9);
 * //......take a while
 * console.log('dj2 ',dj2.getSync());//might be null
 * 
 * 
 * let dj3 = new dynamic_json.DynamicJSON('channel_list.json', 9);
 * dj3.get((err,val)=>{
 * 	console.log('dj3', val);
 * });
 * 
 * let channel_list = await new dynamic_json.DynamicJSON('channel_list', 9).get();
 */
class DynamicJSON {
	constructor(filename, expired, callback) {
		if (!instance_dict.hasOwnProperty(filename)) {
			instance_dict[filename] = this;
			this.filename = filename;
			this.expired = expired * 1000;
			this._refresh_data(true, (err, code) => {
				if (callback) callback(err?null:code);
			});
		}
		return instance_dict[filename];
	}

	_refresh_data(loop, callback) {
		let self = this;
		dfilecol.get({
			'name': self.filename
		}, ['code', 'language']).then(result=>{
			if (result && !isEmpty(result)) {
				let code = result['language'] == 'json' ? JSON.parse(result['code']) : result['code'];
				self.json = code;
				if (loop) setTimeout(() => {
					self._refresh_data(true)
				}, self.expired);
				if (callback) callback(null, code);
			} else {
				if (loop) setTimeout(() => {
					self._refresh_data(true)
				}, self.expired / 2);
				if (callback) callback('file not found.');
			}
		});
	}

	getSync() {
		let self = this;
		let ret;
		if (self.json && !isEmpty(self.json)) {
			ret = self.json;
		} else {
			self._refresh_data(false);
		}
		return ret;
	}

	get(callback) {
		if (callback) { // 回调式
			let self = this;
			if (self.json && !isEmpty(self.json)) {
				callback(null, self.json);
			} else {
				self._refresh_data(false, callback);
			}
		} else { // promise 式
			return new Promise((resolve, reject) => {
				let self = this;
				if (self.json && !isEmpty(self.json)) {
					resolve(self.json);
				} else {
					self._refresh_data(false, (err, code) => {
						if (err) reject(err);
						resolve(code);
					});
				}
			})
		}
	}
}

exports.DynamicJSON = DynamicJSON;